package com.event.core.context;

import com.event.common.face.IAnnotationHandle;
import com.event.common.model.ClassAnnotationEvent;
import com.event.common.model.MethodAnnotationEvent;
import com.event.core.properties.AnnotationEventProperties;
import com.event.core.listener.AnnotationListener;
import com.google.common.eventbus.EventBus;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/*
 * @description 注解上下文
 * @author Bing
 * @date 2024/10/8 14:06
 **/
public class AnnotationContext {
    /**
     * 事件总线
     */
    private EventBus eventBus = new EventBus();
    /**
     * 注解注册
     */
    private List<Class<? extends Annotation>> registerAnnotations;
    /**
     * 类注解事件
     */
    private List<ClassAnnotationEvent> classAnnotationEvents = new ArrayList<>();
    /**
     * 方法注解事件
     */
    private List<MethodAnnotationEvent> methodAnnotationEvents = new ArrayList<>();
    /**
     * 注解配置
     */
    private AnnotationEventProperties annotationEventProperties;

    public AnnotationContext(AnnotationEventProperties annotationEventProperties, IAnnotationHandle annotationHandle) {
        this.annotationEventProperties = annotationEventProperties;
        this.registerAnnotations = annotationEventProperties.getAnnotations();
        eventBus.register(new AnnotationListener(annotationHandle));
    }

    public AnnotationEventProperties getAnnotationEventProperties() {
        return this.annotationEventProperties;
    }

    public List<Class<? extends Annotation>> getRegisterAnnotations() {
        return registerAnnotations;
    }

    public List<ClassAnnotationEvent> getClassAnnotationEvents() {
        return classAnnotationEvents;
    }

    public List<ClassAnnotationEvent> getClassAnnotationEvents(Predicate<ClassAnnotationEvent> predicate) {
        return classAnnotationEvents.stream().filter(predicate).collect(Collectors.toList());
    }

    public List<MethodAnnotationEvent> getMethodAnnotationEvents() {
        return methodAnnotationEvents;
    }

    /**
     * 方法注解事件
     * @param methodAnnotationEvent
     */
    public void methodEvent(MethodAnnotationEvent methodAnnotationEvent){
        synchronized (methodAnnotationEvents){
            methodAnnotationEvents.add(methodAnnotationEvent);
        }
        eventBus.post(methodAnnotationEvent);
    }

    /**
     * 类注解事件
     * @param classAnnotationEvent
     */
    public void classEvent(ClassAnnotationEvent classAnnotationEvent){
        synchronized (classAnnotationEvents){
            classAnnotationEvents.add(classAnnotationEvent);
        }
        eventBus.post(classAnnotationEvent);
    }
}
